Computers and data processing systems are made up of many subsystems, each to perform a portion of a processing task. One way to understand the operation of an overall system is to examine the interfaces subsystems present to each other. For example, a memory module may accept address signals, then copy data on a data bus into a memory location selected by the address when a strobe signal is asserted. Other subsystems may perform more complex functions by combining or repeatedly invoking simpler operations of lower-level units.
The interfaces can be analyzed as promises or guarantees that a module makes to its clients: “if you do A, then I will do B.” Often, A and B are complex, interlocking protocols with ordering requirements or timing parameters that must be respected to ensure both deterministic and correct operation. (Violating timing requirements may cause spurious data errors, while violating order of operation rules may impair a system's logical function.)
Software often relies on interface “promises” of hardware modules. A common programming paradigm called a producer/consumer (“P/C”) relationship provides an example of how changing an interface can break a system. In a P/C relationship, one process (the producer) generates data, then sets a flag when it is finished. Another process (the consumer) waits for the flag to be set, then begins to use the data. However, both data and flag may be simply values stored in memory, and logically indistinguishable to other software or hardware modules involved in reading or writing the values. If the producer writes the data and then sets the flag, but some other subsystem re-orders the memory operations so that the flag is set before the data is written, the consumer may begin processing prematurely. This example shows how failing to respect ordering interfaces can cause logical errors. (The example is of an extremely simple P/C relationship, but many other software relationships can be decomposed or logically reduced to an equivalent of a P/C relationship.)
When many modules are involved in a processing operation, it can be challenging to coordinate their interactions to achieve acceptable overall performance. Furthermore, a module's interfaces or functions may be altered when a new design permits the module to be improved in some way (e.g. to be made smaller, faster, or less expensive). These changes can ripple through related subsystems, requiring corresponding changes to maintain expected performance or to fully realize the benefits of the improved module.
Interfaces between memory and peripheral devices represent one area where careful analysis and adjustment of subsystem interactions can yield significant gains.